const defaults = {
	timeout:0
}
class Axios {
	constructor(instanceConfig={}) {
		this.defaults = instanceConfig
	}
	// configOrUrl:地址或配置对象
	// config:配置对象
	request(configOrUrl={},config={}){
		// 第二个参数是配置对象
		if(typeof configOrUrl === "string"){
			config.url = configOrUrl;
		}else config = configOrUrl;

		// 合并配置对象
		config = {
			...this.defaults,
			...config
		}
		// 设置请求方式
		config.method = (config.method || "get").toLowerCase();

		const {headers={}} = config;
		// 使用baseURL
		if(config.baseURL && !config.url.startsWith("http://")){
			config.url = config.baseURL+config.url;
		}

		// params:{age:12,sex:"男“}======> age=12&sex=男
		if(config.params){
			config.url = config.url+"?"+Object.keys(config.params).map(key=>key+"="+config.params[key]).join("&")
		}

		// 发送ajax请求
		const _dispatchRequest = function(){
			return new Promise(function(resolve,reject){
				const request = new XMLHttpRequest();
				// 指定响应体的格式为json
				request.responseType = "json";
				request.timeout = config.timeout;
				request.open(config.method,config.url);
				// 设置请求头
				for(let key in headers){
					request.setRequestHeader(key,headers[key])
				}
				// 需要在请求头中指定请求体的格式。
				if(config.data){
					// 当config.data的类型是对象：Content-Type:application/json
					// 当config.data的类型是字符串：Content-Type:application/x-www-form-urlencoded
					if(typeof config.data === "object"){
						request.setRequestHeader("Content-Type","application/json");
						config.data = JSON.stringify(config.data);
					}else{
						request.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
					}
				}
				request.send(config.data);// 设置请求体
				// 响应体信息
				request.onload = function(){
					if(request.status>=200 && request.status<300){
						// 当响应体信息接收完毕之后执行
						resolve({
							config,// 配置对象
							data:request.response,// 响应体
							headers:request.getAllResponseHeaders(),// 响应头
							request,
							status:request.status,
							statusText:request.statusText
						})
					}else{
						reject({
							code:"my-ERR_BAD_REQUEST",
							config,
							request,
							status:request.status
						})
					}

				}
				// 超时回调:当请求的时长超过timeout后会触发
				request.ontimeout = function(){
					reject({
						code:"ECONNABORTED",
						config,
						message:"timeout of "+config.timeout+"ms exceeded",
						name:"AxiosError",
						request
					})
				};
				request.onerror = function(){
					reject({
						code:"ERR_NETWORK"
					})
				}
			})

		}
		return _dispatchRequest();
	}
}
function createInstance(defaultConfig){
	const context = new Axios(defaultConfig);
	const instance = Axios.prototype.request.bind(context);
	// 复制context属性至instance当中
	for(let key in context){
		instance[key] = context[key];
	}
	return instance;
}
const axios = createInstance(defaults);
export default axios;